package com.wasion.core.util;

import java.io.ByteArrayOutputStream;
import java.text.DecimalFormat;

/**
 * 
 * @ClassName: ConvertInXBaseUtil
 * @Description: 基于2,10,16进制的数据转换工具
 * @author 高意
 * @date Aug 28, 2012 2:50:33 PM
 * 
 */
public class ConvertInXBaseUtil {

	/**
	 * 二进制串 -> 十进制
	 * 
	 * @param strBinary为二进制串
	 * 
	 * @return 十进制数
	 * @eg: strBinary = 01010101 ----> return 85
	 */
	public static int binary2Decimal(String strBinary) {

		int iDec = 0;
		for (int i = 0; i < strBinary.length(); i++) {
			int temp = Integer.parseInt(strBinary.substring(strBinary.length()
					- (i + 1), strBinary.length() - i));
			iDec += (int) Math.pow(2, i) * temp;
		}

		return iDec;
	}

	/**
	 * 二进制串 -> 十六进制，默认补齐位数
	 * 
	 * @param strBinary为二进制串
	 * 
	 * @return 十六进制数
	 * @eg: strBinary = 01010101 ----> return 55
	 */
	public static String binary2Hex(String strBinary) {

		return binary2Hex(strBinary, true);
	}

	/**
	 * 二进制串 -> 十六进制
	 * 
	 * @param strBinary为二进制串
	 *            , isCovering 是否补齐为2位
	 * 
	 * @return 十六进制数
	 * @eg: strBinary = 01010101 ----> return 55
	 */
	public static String binary2Hex(String strBinary, boolean isCovering) {

		int iDec = binary2Decimal(strBinary);

		return decimal2Hex(iDec, isCovering);
	}

	/**
	 * 二进制 长串 -> 十六进制
	 * 
	 * @param strBinary为二进制串
	 *            , length为分割的长度
	 * 
	 * @return 十六进制数
	 * @eg:strBinary = 10101 01010101 00010101 01010100 01010101 -----> return
	 *               15 55 15 54 55
	 */
	protected static String longBinary2Hex(String strBinary, int length) {

		String strHex = "";
		for (int i = strBinary.length(); i > 0; i -= length) {

			String tString = "";
			if (i / length == 0) {
				tString = strBinary.substring(0, i);
			} else {
				tString = strBinary.substring(i - length, i);
			}
			strHex = binary2Hex(tString) + strHex;
		}

		return strHex;
	}

	/**
	 * 二进制 长串 -> 十六进制，默认补齐位数
	 * 
	 * @param strBinary为二进制串
	 *            , 默认的分割长度为8
	 * 
	 * @return 十六进制数
	 * @eg:strBinary = 10101 01010101 00010101 01010100 01010101 -----> return
	 *               15 55 15 54 55
	 */
	public static String longBinary2Hex(String strBinary) {

		return longBinary2Hex(strBinary, 8);
	}

	/**
	 * 十进制 -> 二进制，默认补齐位数
	 * 
	 * @param decNum为十进制数
	 * 
	 * @return 二进制字符串
	 */
	public static String decimal2Binary(int decNum) {

		return decimal2Binary(decNum, true);
	}

	/**
	 * 十进制 -> 二进制
	 * 
	 * @param decNum为十进制数
	 *            isCovering是否按照四位补齐
	 * 
	 * @return 二进制字符串
	 * @eg:int decNum = 18 ----> return 0001 0010(按照每四位补齐)
	 */
	public static String decimal2Binary(int decNum, boolean isCovering) {

		return decimal2Binary(decNum, isCovering, 8);
	}

	/**
	 * 十进制 -> 二进制
	 * 
	 * @param decNum为十进制数
	 *            , isCovering位数是否补齐 bitNum补齐的位数
	 * 
	 * @return 二进制字符串
	 */
	public static String decimal2Binary(int decNum, boolean isCovering,
			int bitNum) {

		String strBin = Integer.toBinaryString(decNum);

		if (!isCovering || strBin.length() % 8 == 0)
			return strBin;

		int les = bitNum - strBin.length() % bitNum;
		String temp = "";
		for (int i = 0; i < les; i++) {
			temp += "0";
		}

		return temp + strBin;
	}

	/**
	 * 十进制 -> 十六进制(补齐2位), 默认位数补齐
	 * 
	 * @param decNum为十进制数
	 * 
	 * @return 长度为2位的十六进制字符串
	 * @eg: decNum = 85 ----> return 55
	 * @eg: decNum = 5 ----> return 05
	 */
	public static String decimal2Hex(int decNum) {

		return decimal2Hex(decNum, true);
	}

	/**
	 * 十进制 -> 十六进制(补齐2位)
	 * 
	 * @param decNum为十进制数
	 *            , isCovering位数是否补齐8 4 2
	 * 
	 * @return 长度为2位的十六进制字符串
	 * @eg: decNum = 85 ----> return 55
	 * @eg: decNum = 5 ----> return 05
	 */
	public static String decimal2Hex(int decNum, boolean isCovering) {

		String strHex = Integer.toHexString(decNum & 0xFF);

		if (!isCovering)
			return strHex;

		strHex = strHex.length() % 2 == 1 ? "0" + strHex : strHex;

		return strHex;
	}

	/**
	 * 十六进制 -> 十进制
	 * 
	 * @param strHex为的十六进制串
	 * 
	 * @return 十进制数
	 * @eg: byteNum = 55 ----> return 85
	 */
	public static int hex2Decimal(String strHex) {

		return Integer.valueOf(strHex, 16);
	}

	/**
	 * 十六进制 -> 二进制，默认是补齐位数
	 * 
	 * @param strHex为的十六进制串
	 * 
	 * @return 二进制数
	 * @eg: byteNum = 1101 ----> return 0001 0001 0000 0001
	 */
	public static String hex2Binary(String strHex) {

		return hex2Binary(strHex, true);
	}

	/**
	 * 十六进制 -> 二进制
	 * 
	 * @param strHex为的十六进制串
	 *            , isCovering位数是否补齐
	 * 
	 * @return 二进制数
	 * @eg: byteNum = 1101 ----> return 0001 0001 0000 0001
	 */
	public static String hex2Binary(String strHex, boolean isCovering) {

		int iDec = hex2Decimal(strHex);

		return decimal2Binary(iDec, isCovering);
	}

	/**
	 * byte -> 十进制
	 * 
	 * @param byteNum为类型为byte的十进制数
	 * 
	 * @return 十进制数
	 * @eg: byteNum = -128 ----> return 128
	 * @eg: byteNum = 44 ----> return 44
	 * @eg: byteNum = -1 ----> return 255
	 */
	public static int byte2Decimal(byte byteNum) {

		String strHex = Integer.toHexString(byteNum & 0xFF);
		strHex = strHex.length() == 1 ? "0" + strHex : strHex;

		return Integer.valueOf(strHex, 16);
	}

	/**
	 * byte转换为十六进制串，默认补齐2位
	 * 
	 */
	public static String byte2Hex(byte byteNum, boolean isCovering) {

		String strHex = Integer.toHexString(byteNum & 0xFF);

		if (isCovering) {
			strHex = strHex.length() == 1 ? "0" + strHex : strHex;
		}

		// return strHex.equalsIgnoreCase("ee") ? "00" : strHex;
		return strHex;
	}

	/**
	 * byte转换为十六进制串，默认补齐2位
	 * 
	 */
	public static String byte2Hex4EE(byte byteNum) {

		String strHex = Integer.toHexString(byteNum & 0xFF);

		strHex = strHex.length() == 1 ? "0" + strHex : strHex;

		return strHex;
	}

	/**
	 * byte转换为十六进制串，默认补齐2位
	 * 
	 */
	public static String byte2Hex(byte byteNum) {

		return byte2Hex(byteNum, true);
	}

	/**
	 * 
	 * @Title: hexString2ByteArray
	 * @Description: 16进制串转换成byte数组
	 * @param hexStr
	 *            十六进制串
	 * @return
	 * @throws
	 */
	public static byte[] hexString2ByteArray(String hexStr) {

		int len = hexStr.length();
		byte[] data = new byte[len / 2];

		for (int i = 0; i < len; i += 2) {
			data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4) + Character
					.digit(hexStr.charAt(i + 1), 16));
		}

		return data;
	}

	/**
	 * 
	 * @Title: byteArray2HexStr
	 * @Description: byte数组转换为16进制串，中间以空格分隔
	 * @param
	 * @return
	 * @throws
	 */
	public static String byteArray2HexStr(byte[] data) {

		String strHex = "";

		for (byte b : data) {

			String temp = Integer.toHexString(b & 0xFF);
			temp = temp.length() == 1 ? "0" + temp : temp;
			strHex += (temp + " ");
		}

		if (!StringUtil.isEmpty(strHex))
			strHex = strHex.substring(0, strHex.length() - 1);

		return strHex;
	}

	/*
	 * 16进制数字字符集
	 */
	private static final String HEX_STR = "0123456789ABCDEF";

	/**
	 * 
	 * @Title: decodeAscii
	 * @Description: 将16进制数字解码成字符串，适用于所有字符（包括中文）
	 * @param
	 * @return
	 * @throws
	 */
	public static String decodeAscii(String bytes) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream(
				bytes.length() / 2);

		// 将每2位16进制整数组装成一个字节
		for (int i = 0; i < bytes.length(); i += 2) {
			baos.write((HEX_STR.indexOf(bytes.charAt(i)) << 4 | HEX_STR
					.indexOf(bytes.charAt(i + 1))));
		}

		return new String(baos.toByteArray());
	}

	/**
	 * 
	 * @Title: encodeAscii
	 * @Description: 将字符串编码成Ascii码 再用16进制数字表示,适用于所有字符（包括中文） <br>
	 *               e.g 'a' = 97; => 97 -> 0x61
	 * @param
	 * @return
	 * @throws
	 */
	public static String encodeAscii(String str) {

		// 根据默认编码获取字节数组
		byte[] bytes = str.getBytes();
		StringBuilder sb = new StringBuilder(bytes.length * 2);

		// 将字节数组中每个字节拆解成2位16进制整数
		for (int i = 0; i < bytes.length; i++) {
			sb.append(HEX_STR.charAt((bytes[i] & 0xf0) >> 4));
			sb.append(HEX_STR.charAt((bytes[i] & 0x0f) >> 0));
		}

		return sb.toString();
	}

	/**
	 * 
	 * @Title: decodeShortFloatingNumber
	 * @Description: 短浮点数解码 4044D47B -> 3.075469
	 * @param
	 * @return
	 * @throws
	 */
	public static double decodeShortFloatingNumber(String hexStr) {

		// 十六进制串转二进制串
		String binStr = "";
		for (int i = 0; i < hexStr.length(); i += 2) {
			String temp = hexStr.substring(i, i + 2);
			binStr += ConvertInXBaseUtil.hex2Binary(temp, true);
		}

		// 符号位
		String symbol = binStr.substring(0, 1);

		// 指数位串（阶码表示，8位）
		String exponentStr = binStr.substring(1, 9);
		// 指数
		int exp = ConvertInXBaseUtil.binary2Decimal(exponentStr) - 127;

		// 有效位串（尾码表示）
		String effectiveStr = "1" + binStr.substring(9);

		// 整数部分
		String intStr = "";
		// 小数部分
		String decStr = "";
		if (exp < 0) {
			intStr = "0";
			decStr = effectiveStr.substring(0);
			for (int i = 0; i < Math.abs(exp); i++) {
				decStr = "0" + decStr;
			}
		} else {
			intStr = effectiveStr.substring(0, exp + 1);
			decStr = effectiveStr.substring(exp + 1);
		}

		// 二进制串转十进制整数
		int i = ConvertInXBaseUtil.binary2Decimal(intStr);

		// 二进制小数转十进制小数
		double d = 0.0;
		double step = 1.0;
		for (int j = 0; j < decStr.length(); j++) {
			step /= 2.0;
			if (decStr.substring(j, j + 1).equals("1")) {
				d += step;
			}
		}

		d = symbol.equals("0") ? (i + d) : -1 * (i + d);

		DecimalFormat df = new DecimalFormat("##.######");
		String result = df.format(d);

		return Double.parseDouble(result);
	}

	public static void main(String[] args) {
		int[] arr = { 0xde, 0xF7, 0x37, 0xD5 };
		

	}
}
